package com.example.testone.uiComponents;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.CompoundButton;

import androidx.annotation.ColorInt;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;

import com.example.testone.R;

public class WordsSwitch extends CompoundButton {

    public final static int SIZE_NORMAL = 0;
    public final static int SIZE_SMALL = 1;
    public final static int SIZE_MINI = 2;

    private final static int DEFAULT_SIZE = SIZE_NORMAL;

    private int mSize = DEFAULT_SIZE;
    private boolean mDisable;

    private boolean mIsInitialized;

    @ColorInt
    private int mBgCheckedColor;
    @ColorInt
    private int mBgNotCheckedColor;
    @ColorInt
    private int mSwitchColor;

    private int mWidth;
    private int mHeight;
    private int mSwitchPadding;

    private final Paint mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Path mBgPath = new Path();

    private final Paint mSwitchPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Path mSwitchPath = new Path();
    private float mSwitchRatio;

    private final ValueAnimator mAnimator = ValueAnimator.ofFloat(0f, 1f);

    public WordsSwitch(Context context) {
        super(context);
        init(null);
    }

    public WordsSwitch(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public WordsSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.WordsSwitch);
            mSize = typedArray.getInteger(R.styleable.WordsSwitch_switchSize, DEFAULT_SIZE);
            mDisable = typedArray.getBoolean(R.styleable.WordsSwitch_disable, false);
            typedArray.recycle();
        }

        mBgCheckedColor = ContextCompat.getColor(getContext(), R.color.biz_wg_color_28bea0);
        mBgNotCheckedColor = ColorUtils.blendARGB(ContextCompat.getColor(getContext(), R.color.biz_wg_color_f0f0f0), Color.BLACK, 0.1f);
        mSwitchColor = Color.WHITE;
        mSwitchPaint.setColor(mSwitchColor);

        mSwitchPadding = getContext().getResources().getDimensionPixelSize(R.dimen.width1);
        mAnimator.setDuration(300);
        setClickable(true);

        mIsInitialized = true;
        setCheckedWithAnim(false, isChecked(), false);
        disable(mDisable);
    }

    private void refreshPath() {
        refreshBgPath();
        refreshSwitchPath();
    }

    private void refreshBgPath() {
        float radius = (float) mHeight / 2;
        RectF bgLeftRectF = new RectF(0, 0, 2 * radius, mHeight);
        RectF bgMidRectF = new RectF(radius, 0, mWidth - radius, mHeight);
        RectF bgRightRectF = new RectF(mWidth - 2 * radius, 0, mWidth, mHeight);
        mBgPath.reset();
        mBgPath.addArc(bgLeftRectF, 90, 180);
        mBgPath.addRect(bgMidRectF, Path.Direction.CCW); //逆时针 CW :顺时针
        mBgPath.addArc(bgRightRectF, 270, 180);
    }

    private void refreshSwitchPath() {
        float radius = (float) (mHeight - 2 * mSwitchPadding) / 2;
        float center = (mWidth - mHeight) * mSwitchRatio + (float) mHeight / 2;
        Log.d("GaoChang", "refreshSwitchPath: "+center);
        RectF rectF = new RectF(center - radius, mSwitchPadding, center + radius, mHeight - mSwitchPadding);
        //Log.d("GaoChang:SwitchPath::", "left: "+(center - radius)+"  top:"+mSwitchPadding+"  right:"+(center + radius)+" bottom:"+(mHeight - mSwitchPadding));
        mSwitchPath.reset();
        mSwitchPath.addArc(rectF, 0, 360);
    }

    public void disable(boolean disable) {
        mDisable = disable;
        setAlpha(mDisable ? 0.5f : 1f);
        setEnabled(!mDisable);
    }

    @Override
    public void setChecked(boolean checked) {
        Log.d("GaoChang", "setChecked: "+checked);
        boolean isChecked = isChecked();
        super.setChecked(checked);
        if (mIsInitialized) {
            setCheckedWithAnim(isChecked, checked, true);
        }
    }

    private void setCheckedWithAnim(boolean isChecked, boolean checked, boolean withAnim) {
        if (!withAnim || mAnimator == null) {
            mBgPaint.setColor(checked ? mBgCheckedColor : mBgNotCheckedColor);
            mSwitchRatio = checked ? 1 : 0;
            refreshSwitchPath();
            invalidate();
        } else if (isChecked != checked) {
            if (mAnimator.isRunning()) {
                mAnimator.pause();
                float lastValue = (Float) mAnimator.getAnimatedValue();
                float range;
                if (checked) {
                    mAnimator.setFloatValues(lastValue, 1f);
                    range = 1 - lastValue;
                } else {
                    mAnimator.setFloatValues(lastValue, 0);
                    range = lastValue;
                }
                mAnimator.setDuration((long) (300 * range));
                mAnimator.cancel();
            } else {
                if (checked) {
                    mAnimator.setFloatValues(0, 1f);
                } else {
                    mAnimator.setFloatValues(1f, 0);
                }
                mAnimator.setDuration(300);
            }
            mAnimator.removeAllUpdateListeners();
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float value = (float) animation.getAnimatedValue();
                    int color = ColorUtils.blendARGB(mBgNotCheckedColor, mBgCheckedColor, value);
                    mBgPaint.setColor(color);
                    mSwitchRatio = value;
                    refreshSwitchPath();
                    invalidate();
                }
            });
            mAnimator.start();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mSize == SIZE_NORMAL) {
            mWidth = getContext().getResources().getDimensionPixelSize(R.dimen.width28);
            mHeight = getContext().getResources().getDimensionPixelSize(R.dimen.height16);
        } else if (mSize == SIZE_SMALL) {
            mWidth = getContext().getResources().getDimensionPixelSize(R.dimen.width20);
            mHeight = getContext().getResources().getDimensionPixelSize(R.dimen.height12);

        } else if (mSize == SIZE_MINI) {
            mWidth = getContext().getResources().getDimensionPixelSize(R.dimen.width13);
            mHeight = getContext().getResources().getDimensionPixelSize(R.dimen.height8);
        }

        widthMeasureSpec = MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        refreshPath();
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawPath(mBgPath, mBgPaint);
        canvas.drawPath(mSwitchPath, mSwitchPaint);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mAnimator.cancel();
    }
}
